package com.cw.jeeyt.service.impl.mdata;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cw.jeeyt.common.StringUtils;
import com.cw.jeeyt.common.utils.FileUtils;
import com.cw.jeeyt.common.utils.UploadUtils4;
import com.cw.jeeyt.service.bo.mdata.MdataAreaBo;
import com.cw.jeeyt.service.bo.mdata.MdataAreaExcel;
import com.cw.jeeyt.service.converter.mdata.MdataAreaConverter;
import com.cw.jeeyt.dao.intf.mdata.MdataAreaDao;
import com.cw.jeeyt.dao.model.mdata.MdataAreaDo;
import com.cw.jeeyt.dao.query.mdata.MdataAreaQuery;
import com.cw.jeeyt.service.intf.mdata.MdataAreaService;
import com.cw.lang.common.utils.CollectionUtil;
import com.cw.lang.common.utils.GsonUtil;
import com.cw.lang.common.utils.SequenceTool;
import com.cw.lang.mybatis.dto.PageInfo;
import com.cw.lang.mybatis.dto.PageParam;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import lombok.extern.slf4j.Slf4j;

/**
 * 地区接口业务实现类
 *
 * @author admin
 * @date 2021-03-26 22:30:39
 */
@Service
@Slf4j
public class MDataAreaServiceImpl implements MdataAreaService {
    @Autowired
    private MdataAreaDao mdataAreaDao;

    @Value("${uploadFilePath}")
    private String uploadFilePath;
    @Value("${mdataArea.countryCode}")
    private String countryCode;

    /**
     * 新增地区
     *
     * @param request 条件
     * @return Long
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String insert(MdataAreaBo request) {
        if (request == null) {
            return null;
        }
        String id = SequenceTool.nextId();
        request.setAreaId(id);
        request.setCreateTime(new Date());
        request.setUpdateTime(new Date());
        mdataAreaDao.insertBySelective(MdataAreaConverter.bo2Do(request));
        return id;
    }

    /**
     * 更新地区
     *
     * @param request 条件
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean modify(MdataAreaBo request) {
        if (request == null) {
            return false;
        }
        request.setUpdateTime(new Date());
        mdataAreaDao.updateBySelective(MdataAreaConverter.bo2Do(request));
        return true;
    }

    /**
     * 删除地区
     *
     * @param request 条件
     * @return boolean
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(MdataAreaBo request) {
        if (request == null) {
            return false;
        }
        return mdataAreaDao.deleteByKey(request.getAreaId()) > 0;
    }

    /**
     * 分页查询地区
     *
     * @param request 条件
     * @return PageInfo<MdataAreaBo>
     */
    @Override
    public PageInfo<MdataAreaBo> selectPage(MdataAreaBo request, PageParam pageParam) {
        PageInfo<MdataAreaDo> pageInfo = mdataAreaDao.selectPage(MdataAreaQuery.builder()
            .areaCode(request.getAreaCode())
            .areaId(request.getAreaId())
            .areaName(request.getAreaName())
            .cityCode(request.getCityCode())
            .cityId(request.getCityId())
            .cityName(request.getCityName())
            .provinceCode(request.getProvinceCode())
            .provinceName(request.getProvinceName())
            .build(), pageParam);
        List<MdataAreaBo> mdataAreas = MdataAreaConverter.doList2BoList(pageInfo.getList());
        return new PageInfo<>(pageInfo, mdataAreas);
    }

    /**
     * 查询地区详情信息
     *
     * @param request 条件
     * @return MdataAreaBo
     */
    @Override
    public MdataAreaBo queryDetail(MdataAreaBo request) {
        if (request == null) {
            return null;
        }
        return MdataAreaConverter.do2Bo(mdataAreaDao.selectByKey(request.getAreaId()));
    }

    /**
     * 根据条件查询地区
     *
     * @param request 条件
     * @return List<MdataAreaBo>
     */
    @Override
    public List<MdataAreaBo> queryList(MdataAreaBo request) {
        if (request == null) {
            return null;
        }
        return MdataAreaConverter.doList2BoList(mdataAreaDao.selectByExample(MdataAreaQuery.builder()
            .areaCode(request.getAreaCode())
            .areaId(request.getAreaId())
            .areaName(request.getAreaName())
            .cityCode(request.getCityCode())
            .cityId(request.getCityId())
            .cityName(request.getCityName())
            .provinceCode(request.getProvinceCode())
            .provinceName(request.getProvinceName())
            .build()));
    }

    /**
     * 根据key查询地区
     *
     * @param areaId
     * @return
     */
    @Override
    public MdataAreaBo selectByKey(String areaId) {

        return MdataAreaConverter.do2Bo(mdataAreaDao.selectByKey(areaId));
    }

    /**
     * 导入接口文档
     */
    @Override
    public void importMDataArea(HttpServletRequest request) {

        List<UploadUtils4.UploadResult> filePathList = UploadUtils4.getInstance().uploadFile(uploadFilePath,request);
        if (filePathList != null && !filePathList.isEmpty()) {
            for (UploadUtils4.UploadResult uploadResult : filePathList) {
                //导入接口文档信息
                ImportParams params = new ImportParams();
                params.setTitleRows(0);
                params.setStartSheetIndex(0);
                List<MdataAreaExcel> mdataAreaList = ExcelImportUtil.importExcel(new File(uploadResult.getFilePath()),
                    MdataAreaExcel.class, params);
                if (CollectionUtil.isEmpty(mdataAreaList)) {
                    return;
                }
                //保存省市区域数据到数据库中
                saveMdataAreaInfo(mdataAreaList);
            }
        }
    }

    @Override
    public void downloadJsonData(HttpServletRequest request, HttpServletResponse response) {
        //查询出省/直辖市
        List<MdataAreaDo> provinceInfos = mdataAreaDao.queryAllProvinceCode();
        StringBuffer sb = new StringBuffer();
        if (CollectionUtil.isEmpty(provinceInfos)) {
            return;
        }
        sb.append("{");
        //拼接国家-省/直辖市的json串
        sb.append("\"" + countryCode + "\"" + ":");
        sb.append("{");
        int i = 0;
        for (MdataAreaDo province : provinceInfos) {
            if (i != provinceInfos.size() - 1) {
                sb.append(
                    "\"" + province.getProvinceCode() + "\"" + ":" + "\"" + province.getProvinceName() + "\"" + ",");
            } else {
                sb.append("\"" + province.getProvinceCode() + "\"" + ":" + "\"" + province.getProvinceName() + "\"");
            }
            i++;
        }
        sb.append("},");
        //拼接省-市的json串
        for (MdataAreaDo province : provinceInfos) {
            sb.append("\"" + province.getProvinceCode() + "\"" + ":");
            sb.append("{");
            List<MdataAreaDo> cityInfos = mdataAreaDao.queryAllCityCodeByProvinceCode(province.getProvinceCode());
            i = 0;
            for (MdataAreaDo city : cityInfos) {
                if (i != cityInfos.size() - 1) {
                    sb.append("\"" + city.getCityCode() + "\"" + ":" + "\"" + city.getCityName() + "\"" + ",");
                } else {
                    sb.append("\"" + city.getCityCode() + "\"" + ":" + "\"" + city.getCityName() + "\"");
                }
                i++;
            }
            sb.append("},");
        }
        for (MdataAreaDo province : provinceInfos) {
            List<MdataAreaDo> cityInfos = mdataAreaDao.queryAllCityCodeByProvinceCode(province.getProvinceCode());
            for (MdataAreaDo city : cityInfos) {
                sb.append("\"" + city.getCityCode() + "\"" + ":");
                sb.append("{");
                List<MdataAreaDo> areaInfos = mdataAreaDao.queryAllAreaCodeByCityCode(city.getCityCode());
                i = 0;
                for (MdataAreaDo area : areaInfos) {
                    if (i != areaInfos.size() - 1) {
                        sb.append("\"" + area.getAreaCode() + "\"" + ":" + "\"" + area.getAreaName() + "\"" + ",");
                    } else {
                        sb.append("\"" + area.getAreaCode() + "\"" + ":" + "\"" + area.getAreaName() + "\"");
                    }
                    i++;
                }
                sb.append("},");
            }
        }
        String jsonData = sb.substring(0,sb.length()-1) + "}";
        String jsonFile = uploadFilePath + File.separator + "pcadata.json";
        File file = new File(jsonFile);
        if(file.exists()){
            file.delete();
        }
        FileUtils.createFile(jsonFile);
        FileUtils.writeToFile(jsonFile, jsonData);
        FileUtils.downFile(file, request, response);
    }

    /**
     * 保存省市区域数据到数据库中
     * //思路
     * 如果编码后面四个0，则认为是省，直辖市，放到省直辖市的map中
     * 如果编码后面两个0，则认为是市，放到市的map中，
     * 否则认为是区，县，通过截取前两位，查出省，直辖市，通过截取前四位，查出市，同时做对应的落库处理
     *
     * @param mdataAreaList
     */
    private void saveMdataAreaInfo(List<MdataAreaExcel> mdataAreaList) {
        Map<String, String> provinceMap = new HashMap<>();
        Map<String, String> cityMap = new HashMap<>();
        mdataAreaList.forEach(mdataAreaExcel -> {
            //行政区划编码
            String administrativeDivisions = mdataAreaExcel.getAdministrativeDivisions();
            //单位名称
            String unitName = mdataAreaExcel.getUnitName();
            //将省，直辖市添加到省,市map
            if (administrativeDivisions.endsWith("0000")) {
                provinceMap.put(administrativeDivisions.substring(0, administrativeDivisions.length() - 4), unitName);
            } else if (administrativeDivisions.endsWith("00")) {
                cityMap.put(administrativeDivisions.substring(0, administrativeDivisions.length() - 2), unitName);
            }
        });
        //添加区/县信息到行政区划数据库中
        log.info(GsonUtil.objectToJsonString(provinceMap));
        log.info(GsonUtil.objectToJsonString(cityMap));
        List<MdataAreaDo> mdataAreaDos = new ArrayList<>();
        mdataAreaList.forEach(mdataAreaExcel -> {
            //行政区划编码
            String administrativeDivisions = mdataAreaExcel.getAdministrativeDivisions().trim();
            //单位名称
            String unitName = mdataAreaExcel.getUnitName().trim();
            //将省，直辖市添加到省,市map
            if (!administrativeDivisions.endsWith("00")) {
                //截取前4位作为市,截取前两位作为省
                String provinceCode = administrativeDivisions.substring(0, administrativeDivisions.length() - 4);
                String cityCode = administrativeDivisions.substring(0, administrativeDivisions.length() - 2);
                String provinceName = provinceMap.get(provinceCode);
                String cityName = cityMap.get(cityCode);
                if (StringUtils.isBlank(cityName)) {
                    cityName = provinceMap.get(cityCode.substring(0, cityCode.length() - 2));
                }
                MdataAreaDo mdataAreaDo = new MdataAreaDo();
                mdataAreaDo.setAreaId(administrativeDivisions);
                mdataAreaDo.setCreateTime(new Date());
                mdataAreaDo.setUpdateTime(new Date());
                mdataAreaDo.setProvinceCode(provinceCode);
                mdataAreaDo.setProvinceName(provinceName);
                mdataAreaDo.setCityCode(cityCode);
                mdataAreaDo.setCityName(cityName);
                mdataAreaDo.setAreaCode(administrativeDivisions);
                mdataAreaDo.setAreaName(unitName);
                mdataAreaDo.setCityId(cityCode + "00");
                mdataAreaDos.add(mdataAreaDo);
            }
        });
        if (CollectionUtil.isNotEmpty(mdataAreaDos)) {
            //先清理行政区划数据表信息
            mdataAreaDao.cleanData();
            //保存行政区划信息
            mdataAreaDao.insertList(mdataAreaDos);
        }
    }
}
